package com.gitee.wsl.common.chart.render.shape.bar

import android.graphics.*
import com.gitee.wsl.android.ext.base.setAlphaComponent
import com.gitee.wsl.ext.base.ColorExt
import com.gitee.wsl.math.Math
import com.gitee.wsl.jvm.math.add
import com.gitee.wsl.jvm.math.sub
import kotlin.math.cos
import kotlin.math.sin

class Bar3D: Bar() {
    //3D效果厚度
    var thickness = 20f

    //偏移角色度
    var angle = 45f

    //透明度
    var alpha = 200

    //3D浅色画笔
    var mPaint3D: Paint = Paint()
    var mPaintBase: Paint = Paint()
    var mPaintBase3D: Paint = Paint()

    //3D效果厚度
    var axisBaseThickness = 20f

    //底盘颜色
    var axisBaseColor = Color.rgb(73, 172, 72)

    var rectangle2DPath = Path()
    var linePaint = Paint()


    /**
     * 绘制柱形标签
     * @param text    文本内容
     * @param x        x坐标
     * @param y        y坐标
     * @param canvas    画布
     */
    fun renderBarItemLabel(text: String, x: Float, y: Float, canvas: Canvas) {
        drawBarItemLabel(text, x, y, canvas)
    }

    /**
     * 得到水平偏移量
     * @param thickness    厚度
     * @param angle        角度
     * @return    水平偏移量
     */
    fun getOffsetX(thickness: Float, angle: Float): Float {
        return (thickness * cos(angle * Math.PI / 180)).toFloat()
    }


    /**
     * 得到垂直偏移量
     * @param thickness    厚度
     * @param angle        角度
     * @return    垂直偏移量
     */
    fun getOffsetY(thickness: Float, angle: Float): Float {
        return (thickness * sin(angle * Math.PI / 180)).toFloat()
    }


    /**
     * 返回水平偏移量
     * @return 偏移量
     */
    val offsetX:Float
      get() = getOffsetX(axisBaseThickness, angle)

    /**
     * 返回垂直偏移量
     * @return 偏移量
     */
    val offsetY: Float
        get() = getOffsetY(axisBaseThickness, angle)



    /**
     * 计算同标签多柱形时的Y分隔
     * @param YSteps    Y轴步长
     * @param barNumber  柱形个数
     * @return 返回单个柱形的高度及间距
     */
    fun getBarHeightAndMargin(YSteps: Float, barNumber: Int): FloatArray? {
        return calcBarHeightAndMargin(YSteps, barNumber)
    }

    /**
     * 计算同标签多柱形时的X分隔
     * @param XSteps    X轴步长
     * @param barNumber 柱形个数
     * @return 返回单个柱形的宽度及间距
     */
    fun getBarWidthAndMargin(XSteps: Float, barNumber: Int): FloatArray? {
        return calcBarWidthAndMargin(XSteps, barNumber)
    }


    /**
     * 竖向柱形的3D效果
     * @param barLeft    左边X坐标
     * @param barTop    顶部Y坐标
     * @param barRight    右边X坐标
     * @param barBottom    底部Y坐标
     * @param color        柱形颜色
     * @param canvas    画布
     */
    fun renderVertical3DBar(
        barLeft: Float, barTop: Float,
        barRight: Float, barBottom: Float,
        color: Int,
        canvas: Canvas
    ) {
        //浅色	
        val lightColor = ColorExt.setAlphaComponent(color, alpha)
        barPaint.color = color
        mPaint3D.color = lightColor

        //水平偏移量
        //val offsetX =
        //垂直偏移量
        //val offsetY = offsetY

        //Shadow
        val barLeft2:Float = barLeft - offsetX
        val barTop2 = barTop + offsetY
        val barRight2 = barRight - offsetX
        val barBottom2 = barBottom + offsetY

        //顶		
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(barLeft, barTop)
        rectangle2DPath.lineTo(barLeft2, barTop2)
        rectangle2DPath.lineTo(barRight2, barTop2)
        rectangle2DPath.lineTo(barRight, barTop)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, barPaint)

        //右侧边
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(barRight, barTop)
        rectangle2DPath.lineTo(barRight2, barTop2)
        rectangle2DPath.lineTo(barRight2, barBottom2)
        rectangle2DPath.lineTo(barRight, barBottom)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, barPaint)
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(barRight2, barTop2)
        rectangle2DPath.lineTo(barRight2, barBottom2)
        rectangle2DPath.lineTo(barLeft2, barBottom2)
        rectangle2DPath.lineTo(barLeft2, barTop2)
        rectangle2DPath.close()

        //正面 浅色	
        val linearGradient = LinearGradient(
            barLeft2, barBottom2, barRight2, barBottom2, intArrayOf(color, lightColor),
            null, Shader.TileMode.REPEAT
        )
        mPaint3D.shader = linearGradient
        mPaint3D.style = Paint.Style.FILL
        canvas.drawPath(rectangle2DPath, mPaint3D)

        //柱形顶上用白画一个RECT,强化3D效果		 
        linePaint.reset()
        linePaint.style = Paint.Style.STROKE
        linePaint.color = Color.WHITE
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(barLeft2, barTop2)
        rectangle2DPath.lineTo(barRight2, barTop2)
        rectangle2DPath.lineTo(barRight, barTop)
        canvas.drawPath(rectangle2DPath, linePaint)

        //柱形正面画一根白色竖线,强化3D效果
        canvas.drawLine(barRight2, barTop2, barRight2, barBottom2, linePaint)
    }


    /**
     * 竖向3D柱形图的底 座
     * @param baseLeft    左边X坐标
     * @param baseTop    顶部Y坐标
     * @param baseRight    右边X坐标
     * @param baseBottom    底部Y坐标
     * @param canvas    画布
     */
    fun render3DXAxis(
        baseLeft: Float, baseTop: Float,
        baseRight: Float, baseBottom: Float,
        canvas: Canvas
    ) //	  int color,
    {
        //浅色	
        val baseLightColor = ColorExt.setAlphaComponent(axisBaseColor, alpha)
        mPaintBase.color = axisBaseColor
        mPaintBase3D.color = baseLightColor

        //水平偏移量
        //val offsetX = getOffsetX()
        //垂直偏移量
        //val offsetY = offsetY

        //Shadow
        val baseLeft2 =  Math.sub(baseLeft, offsetX)
        val baseTop2 =  Math.add(baseTop, offsetY)
        val baseRight2 =  Math.sub(baseRight, offsetX)
        val baseBottom2 =  Math.add(baseBottom, offsetY)

        //顶 用浅色
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(baseLeft, baseBottom)
        rectangle2DPath.lineTo(baseLeft2, baseBottom2)
        rectangle2DPath.lineTo(baseRight2, baseBottom2)
        rectangle2DPath.lineTo(baseRight, baseBottom)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, mPaintBase3D)

        //右侧边 深色
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(baseRight, baseTop)
        rectangle2DPath.lineTo(baseRight2, baseTop2)
        rectangle2DPath.lineTo(baseRight2, baseBottom2)
        rectangle2DPath.lineTo(baseRight, baseBottom)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, mPaintBase)

        //正面 深色	 
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(baseRight2, baseTop2)
        rectangle2DPath.lineTo(baseRight2, baseBottom2)
        rectangle2DPath.lineTo(baseLeft2, baseBottom2)
        rectangle2DPath.lineTo(baseLeft2, baseTop2)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, mPaintBase)

        //水平偏移量		
        //Paint paint = new Paint();
        linePaint.reset()
        linePaint.color = axisBaseColor
        linePaint.style = Paint.Style.FILL
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(baseRight2, baseBottom2)
        rectangle2DPath.lineTo(baseRight, baseBottom)
        rectangle2DPath.lineTo(
            baseRight,
            Math.add(baseBottom, axisBaseThickness)
        )
        rectangle2DPath.lineTo(baseRight2, baseBottom2 + axisBaseThickness)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, linePaint)
        linePaint.color = baseLightColor
        canvas.drawRect(
            baseLeft2, baseBottom2, baseRight2,
            baseBottom2 + axisBaseThickness, linePaint
        )
    }

    /**
     * 横向3D柱形图
     * @param barLeft    左边X坐标
     * @param barTop    顶部Y坐标
     * @param barRight    右边X坐标
     * @param barBottom    底部Y坐标
     * @param color    柱形颜色
     * @param canvas    画布
     */
    fun renderHorizontal3DBar(
        barLeft: Float, barTop: Float,
        barRight: Float, barBottom: Float,
        color: Int,
        canvas: Canvas
    ) {
        if (barTop.compareTo(barBottom) == 0) return

        //浅色
        val lightColor = ColorExt.setAlphaComponent(color, alpha)
        barPaint.color = color
        mPaint3D.color = lightColor

        //水平偏移量
        //val offsetX = getOffsetX()
        //垂直偏移量
        //val offsetY = offsetY

        //Shadow
        val barLeft2 =  Math.sub(barLeft, offsetX)
        val barTop2 =  Math.add(barTop, offsetY)
        val barRight2 =  Math.sub(barRight, offsetX)
        val barBottom2 =  Math.add(barBottom, offsetY)

        //右侧边 浅色
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(barRight, barTop)
        rectangle2DPath.lineTo(barRight, barBottom)
        rectangle2DPath.lineTo(barRight2, barBottom2)
        rectangle2DPath.lineTo(barRight2, barTop2)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, mPaint3D)

        //正面	
        canvas.drawRect(barLeft2, barTop2, barRight2, barBottom2, mPaint3D)

        //顶
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(barLeft, barTop)
        rectangle2DPath.lineTo(barLeft2, barTop2)
        rectangle2DPath.lineTo(barRight2, barTop2)
        rectangle2DPath.lineTo(barRight, barTop)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, barPaint)

        //轮廓线
        linePaint.reset()
        linePaint.color = Color.WHITE
        linePaint.style = Paint.Style.STROKE
        canvas.drawLine(barLeft2, barTop2, barRight2, barTop2, linePaint)
        canvas.drawLine(barRight2, barTop2, barRight2, barBottom2, linePaint)
        canvas.drawLine(barRight, barTop, barRight2, barTop2, linePaint)
    }


    /**
     * 横向3D柱形图的底 座
     * @param baseLeft    左边X坐标
     * @param baseTop    顶部Y坐标
     * @param baseRight    右边X坐标
     * @param baseBottom    底部Y坐标
     * @param canvas    画布
     */
    fun render3DYAxis(
        baseLeft: Float, baseTop: Float,
        baseRight: Float, baseBottom: Float,
        canvas: Canvas
    ) {
        //浅色
        val baseLightColor = ColorExt.setAlphaComponent(axisBaseColor, alpha)
        mPaintBase.color = axisBaseColor
        mPaintBase3D.color = baseLightColor

        //水平偏移量
        //val offsetX = getOffsetX()
        //垂直偏移量
        //val offsetY = offsetY

        //Shadow
        val baseLeft2 =  Math.sub(baseLeft, offsetX)
        val baseTop2 =  Math.add(baseTop, offsetY)
        val baseBottom2 =  Math.add(baseBottom, offsetY)

        //左侧面
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(baseLeft, baseTop)
        rectangle2DPath.lineTo(baseLeft2, baseTop2)
        rectangle2DPath.lineTo(baseLeft2, baseBottom2)
        rectangle2DPath.lineTo(baseLeft, baseBottom)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, mPaintBase)

        //正面
        canvas.drawRect(
            baseLeft2, baseTop2,
            Math.sub(baseLeft2, offsetX), baseBottom2, mPaintBase3D
        )

        //侧面顶		
        rectangle2DPath.reset()
        rectangle2DPath.moveTo(baseLeft, baseTop)
        rectangle2DPath.lineTo(baseLeft2, baseTop2)
        rectangle2DPath.lineTo( Math.sub(baseLeft2, offsetX), baseTop2)
        rectangle2DPath.lineTo( Math.sub(baseLeft, offsetX), baseTop)
        rectangle2DPath.close()
        canvas.drawPath(rectangle2DPath, mPaintBase3D)
    }
    
}